#include <jni.h>
#include <string>
#include <memory>
#include "code/base64.h"
#include "code/crc32.h"
#include "protocol/protocol.h"
#include "protocol/transate.h"

static std::shared_ptr<protocol> mProtocolPush;
static std::shared_ptr<transate> mTransatePush;

static std::shared_ptr<protocol> mProtocolPop;
static std::shared_ptr<transate> mTransatePop;

const static int COMMAND_REFRESH = 1;
const static int COMMAND_CONFIG_NETWORK = 2;
const static int COMMAND_DEVICE_STATE = 3;

#if 0
extern "C" JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_DemoApplication_init(
        JNIEnv *env,
        jobject /* this */) {

    mProtocolPush.reset(new protocol(env));
    mTransatePush.reset(new transate());

    mProtocolPop.reset(new protocol(env));
    mTransatePop.reset(new transate());
    chksum_crc32gentab();
}
#endif
extern "C"
JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_MessageP2P_sendRefreshCommand(JNIEnv *env, jobject instance) {
    char realCommand[1024] = {};
    mProtocolPush->setEnv(env);
    uint8_t len = mProtocolPush->refreshCommand(realCommand);

    mTransatePush->packCommand(env,instance,realCommand,len,COMMAND_REFRESH);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_MessageP2P_sendNetworkCommand(JNIEnv *env, jobject instance,
                                                         jstring ssid_, jstring pwd_, jint mode) {
    const char *ssid = env->GetStringUTFChars(ssid_, 0);
    const char *pwd = env->GetStringUTFChars(pwd_, 0);

    char realCommand[1024] = {};
    netConf conf;
    conf.ssid_len = strlen(ssid);
    memcpy(conf.ssid,ssid,conf.ssid_len);

    conf.pwd_len = strlen(pwd);
    memcpy(conf.pwd,pwd,conf.pwd_len);
    conf.encrypMode = mode;
    mProtocolPush->setEnv(env);
    uint8_t len = mProtocolPush->configNetworkCommand(&conf,realCommand);
    // TODO

    mTransatePush->packCommand(env,instance,realCommand,len,COMMAND_CONFIG_NETWORK);
    env->ReleaseStringUTFChars(ssid_, ssid);
    env->ReleaseStringUTFChars(pwd_, pwd);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_MessageP2P_sendDeviceStateCommand(JNIEnv *env, jobject instance,
                                                             jint state,jint addr) {
    char realCommand[1024] = {};
    mProtocolPush->setEnv(env);
    std::shared_ptr<deviceState> devState(new deviceState);
    devState->addr = addr;
    devState->state = state;
    uint8_t len = mProtocolPush->deviceStateCommand(devState.get(), realCommand);
    // TODO

    mTransatePush->packCommand(env,instance,realCommand,len,COMMAND_DEVICE_STATE);
    // TODO
}

extern "C"
JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_DemoRole_doCommand(JNIEnv *env, jclass type, jstring cmd_) {
    const char *cmd = env->GetStringUTFChars(cmd_, 0);

    uint8_t command[4096] = {};
    uint8_t ret[1024] = {};
    uint8_t retVal = 0;
    uint32_t commandLen = 0;
    uint16_t sessionID = 0;

    if(mTransatePop->unpackCommand(cmd,strlen(cmd),&sessionID)) {
        commandLen = mTransatePop->popCommand(sessionID,command);
        mProtocolPop->setEnv(env);
        mProtocolPop->process(command, commandLen);
    }


    env->ReleaseStringUTFChars(cmd_, cmd);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_DemoApplication_setState(JNIEnv *env, jobject instance, jint state) {
    mProtocolPush->setEnv(env);
    mProtocolPush->setState(state);
    mProtocolPop->setEnv(env);
    mProtocolPop->setState(state);

}extern "C"
JNIEXPORT void JNICALL
Java_com_gree_syq_wifidemo_DemoApplication_init(JNIEnv *env, jobject instance) {

    mProtocolPush.reset(new protocol(env));
    mTransatePush.reset(new transate());

    mProtocolPop.reset(new protocol(env));
    mTransatePop.reset(new transate());
    chksum_crc32gentab();

}